package lnet

import (
	"fmt"
	"linx/liface"
	"linx/utils"
	"net"
)

// lserver的接口实现，定义一个server的服务器模块
type Server struct {
	Name      string // 服务器名称
	IPVersion string // IP版本号
	IP        string // IP地址
	Port      int    // 端口

	MsgHandler liface.IMsgHandler  // 当前server的所有router
	ConnMgr    liface.IConnManager // 连接管理器

	OnConnStart func(conn liface.IConnection) // 创建之后自动调用Hook函数
	OnConnStop func(conn liface.IConnection) // 销毁之后自动调用Hook函数
}

func (s *Server) AddRouter(msgID uint32, router liface.IRouter) {
	s.MsgHandler.AddRouter(msgID, router)
	fmt.Println("Add Router Success!")
}

// 新建一个Server的方法
func NewServer(name string) liface.IServer {
	s := &Server{
		Name:       utils.GlobalObject.Name,
		IPVersion:  "tcp4",
		IP:         utils.GlobalObject.Host,
		Port:       utils.GlobalObject.TcpPort,
		MsgHandler: NewMsgHandle(),
		ConnMgr:    NewConnManager(),
	}
	return s
}

// 开启服务器
func (s *Server) Start() {
	fmt.Printf("[linx] conf:%+v\n", utils.GlobalObject)
	fmt.Printf("服务器已启动，监听地址为：%s，端口为：%d\n", s.IP, s.Port)
	go func() {
		// 开启消息队列及worker工作流
		s.MsgHandler.StartWorkerPool()
		// 获取一个 TCP 的 Addr
		addr, err := net.ResolveTCPAddr(s.IPVersion, fmt.Sprintf("%s:%d", s.IP, s.Port))
		if err != nil {
			fmt.Printf("TCP服务开启失败，err:%s\n", err.Error())
			return
		}
		// 已经监听成功
		tcp, err := net.ListenTCP(s.IPVersion, addr)
		if err != nil {
			fmt.Printf("监听服务开启失败，err:%s\n", err.Error())
			return
		}
		var cid uint32
		cid = 0
		for {
			// 如果有客户端链接进来，则accept成功，否则阻塞
			conn, err := tcp.AcceptTCP()
			if err != nil {
				fmt.Printf("AcceptTCP，err:%s\n", err.Error())
				continue
			}

			// 设置最大连接的判断，如果超过则直接关闭新的链接
			if s.ConnMgr.Len() >= utils.GlobalObject.MaxConn {
				fmt.Println("Conn is max:", utils.GlobalObject.MaxConn)
				if err := conn.Close(); err != nil {
					fmt.Println("Close conn err:", err.Error())
				}
				continue
			}

			dealConn := NewConnection(s, conn, cid, s.MsgHandler)
			cid++

			// 启动
			dealConn.Start()
		}
	}()

}

// 停止服务器
func (s *Server) Stop() {
	// 将一些服务的资源、状态、或者一些已经开辟的空间进行回收
	fmt.Println("Server Stop!")
	s.ConnMgr.ClearConn()
}

// 运行服务器
func (s *Server) Serve() {
	s.Start()
	// 其他业务逻辑

	// 阻塞
	select {}
}

func (s *Server) GetConnMgr() liface.IConnManager {
	return s.ConnMgr
}

// 注册 OnConnStart
func(s *Server) SetOnConnStart(hookFunc func(connection liface.IConnection)) {
	s.OnConnStart = hookFunc
}
// 注册 OnConnStop
func(s *Server) SetOnConnStop(hookFunc func(connection liface.IConnection)) {
	s.OnConnStop = hookFunc
}
// 调用 OnConnStart
func(s *Server) CallOnConnStart(connection liface.IConnection) {
	if s.OnConnStart != nil {
		fmt.Println("----------> Call OnConnStart")
		s.OnConnStart(connection)
	}
}
// 调用 OnConnStop
func(s *Server) CallOnConnStop(connection liface.IConnection) {
	if s.OnConnStart != nil {
		fmt.Println("----------> Call OnConnStop")
		s.OnConnStop(connection)
	}
}